package com.hyjx.framework.component.task;

import com.hyjx.framework.common.util.SpringBeanUtil;
import com.hyjx.framework.common.util.StringHelper;
import com.hyjx.framework.common.util.SystemInfoUtil;
import com.hyjx.framework.service.CacheService;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerKey;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 调度任务管理类，负责所有任务的调度
 *
 * @author dijian
 */
@SuppressWarnings("static-access")
public class TaskManager {
    //调度任务对象
    private static Scheduler scheduler;
    private static Logger logger = LoggerFactory.getLogger(TaskManager.class);

    static {
        try {
            scheduler = new StdSchedulerFactory().getDefaultScheduler();
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 缓存定时任务
     */
    public static void init() {
        logger.info(StringHelper.getDateTimeMill() + " 正在缓存定时任务");

        TaskService taskSrv = (TaskService) SpringBeanUtil.getBean("taskServiceImpl");
        List<TaskModel> list = taskSrv.queryAllTask();
        //放入缓存
        Map<String, TaskModel> taskMap = new LinkedHashMap<String, TaskModel>();
        for (TaskModel model : list) {
            taskMap.put(model.getTaskid(), model);
        }
        CacheService.set("sys.task.alltasks", taskMap);
        logger.info(StringHelper.getDateTimeMill() + " 缓存定时任务结束");
    }

    /**
     * 初始化任务
     */
    public static void initTask() {
        logger.info(StringHelper.getDateTimeMill() + " 正在初始化定时任务");
        String ip = SystemInfoUtil.getLocalIp();//获得本机IP
        logger.info("本地服务器ip地址为：" + ip);
        //取缓存
        Map<String, TaskModel> taskMap = getSysTasks();
        for (TaskModel model : taskMap.values()) {
            if ("1".equals(model.getStartflowsys())) {
                if ("1".equals(model.getIssingleton())) {
                    if (ip.equals(model.getIpaddress())) {
                        startTask(model);
                    } else {
                        logger.error("定时任务" + model.getTaskname() + "未启动，原因服务器ip和启动ip不一致." + ip + "!=" + model.getIpaddress());
                    }
                } else {
                    startTask(model);
                }
            }
        }
        logger.info(StringHelper.getDateTimeMill() + " 初始化定时任务结束");
    }

    /**
     * 获取任务的运行状态
     *
     * @param taskid
     * @return
     */
    public static String getTaskStatus(String taskid) {
        try {
            TriggerState ts = scheduler.getTriggerState(new TriggerKey(taskid));
            if (ts == TriggerState.NONE) {
                return "未启动";
            } else if (ts == TriggerState.NORMAL) {
                return "正常";
            } else if (ts == TriggerState.PAUSED) {
                return "暂停";
            } else if (ts == TriggerState.COMPLETE) {
                return "完成";
            } else if (ts == TriggerState.BLOCKED) {
                return "阻塞";
            } else {
                return "异常";
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
            return "异常";
        }
    }

    /**
     * 启动调度任务
     *
     * @param model
     * @return
     */
    public static boolean startTask(TaskModel model) {
        logger.debug("开始加载任务:" + model.getTaskname());
        if (!getTaskStatus(model.getTaskid()).equals("未启动")) {
            logger.debug("该任务已经在运行不能重复添加任务:" + model.getTaskname());
            return false;
        }
        try {
            JobDetailImpl jobdetail = null;
            CronTriggerImpl trigger = new CronTriggerImpl();
            trigger.setKey(new TriggerKey(model.getTaskid()));
            trigger.setName(model.getTaskid());
            trigger.setCronExpression(model.getCronexp()); //0/5 * *  * * ? *
            jobdetail = new JobDetailImpl();
            jobdetail.setName(model.getTaskname());
            jobdetail.setGroup("default");
            JobDataMap jobDataMap = new JobDataMap();

            jobDataMap.put("taskid", model.getTaskid());
            jobDataMap.put("taskname", model.getTaskname());
            jobDataMap.put("tasktype", model.getTasktype());
            jobDataMap.put("classname", model.getClassname());
            jobDataMap.put("methodname", model.getMethodname());
            jobDataMap.put("param1", model.getParam1());
            jobDataMap.put("param2", model.getParam2());
            jobdetail.setJobDataMap(jobDataMap);
            jobdetail.setJobClass((Class<? extends Job>) JobMonitor.class);
            scheduler.scheduleJob(jobdetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        logger.debug("完成加载任务:" + model.getTaskname());
        return true;
    }

    /**
     * 暂停任务
     *
     * @param taskid
     * @return
     */
    public static boolean pauseTask(String taskid) {
        try {
            scheduler.pauseTrigger(new TriggerKey(taskid));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 恢复运行任务
     *
     * @param taskid
     * @return
     */
    public static boolean resumeTask(String taskid) {
        try {
            scheduler.resumeTrigger(new TriggerKey(taskid));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 停止某任务调度
     *
     * @param taskid 任务id
     * @return 成功与否
     */
    public static boolean stopTask(String taskid) {
        try {
            return scheduler.unscheduleJob(new TriggerKey(taskid));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 保存任务日志
     *
     * @param taskid
     * @param taskname
     * @param info
     */
    public static void saveTaskLog(String taskid, String taskname, String info) {
        TaskService taskSrv = (TaskService) SpringBeanUtil.getBean("taskServiceImpl");
        TaskLogModel model = new TaskLogModel();
        model.setLogid(StringHelper.getPrimaryKey());
        model.setMessage(info);
        model.setRunresult("0");
        model.setRuntime(StringHelper.getDateTime());
        model.setTaskid(taskid);
        model.setTaskname(taskname);

        taskSrv.saveTaskLog(model);
    }

    /**
     * 取任务缓存数据
     */
    @SuppressWarnings("unchecked")
    public static Map<String, TaskModel> getSysTasks() {
        return (Map<String, TaskModel>) CacheService.get("sys.task.alltasks");
    }

    /**
     * 取任务缓存数据
     */
    public static TaskModel getTaskById(String taskId) {
        return getSysTasks().get(taskId);
    }
}
